﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
using System.Web;
using System.Web.Routing;
using Microsoft.AspNet.Identity;

namespace LynxWebLog
{
    public class MetaWebLogAPI : IMetaWeblogProvider
    {
        public async Task<BlogInfo[]> GetUserBlogs(string appkey, string userName, string password)
        {
            BlogInfo[] biArr = null;

            HttpClient client = ClientUtility.BlogAPIClient();
            try {
                HttpResponseMessage resp = await client.GetAsync("api/BlogData/?$filter=username eq '" + userName + "'");
                resp.EnsureSuccessStatusCode();

                IEnumerable<BlogData> ibd = await resp.Content.ReadAsAsync<IEnumerable<BlogData>>();
                List<BlogInfo> lbi = new List<BlogInfo>();
                foreach (BlogData bd in ibd) {
                    bd.url = string.Format("{0}/{1}", HttpRuntime.AppDomainAppVirtualPath, bd.url);
                    lbi.Add(new BlogInfo(bd));
                }
                biArr = lbi.ToArray();
            }
            catch { }

            return biArr;
        }

        public async Task<Post[]> GetRecentPosts(string userName, string password, string blogid, int noOfPosts)
        {
            Post[] bpArr = null;
            HttpClient client = ClientUtility.BlogAPIClient();
            try {
                HttpResponseMessage resp = await client.GetAsync("api/PostData/?$filter=blogid eq '" + blogid + "'&$orderby=dateCreated desc");
                resp.EnsureSuccessStatusCode();

                IEnumerable<PostData> ipd = (await resp.Content.ReadAsAsync<IEnumerable<PostData>>()).Take(noOfPosts);
                List<Post> lp = new List<Post>();
                foreach (PostData p in ipd) {
                    HttpResponseMessage rpCat = await client.GetAsync("api/PostCategory/?$filter=postid eq " + p.postid);
                    rpCat.EnsureSuccessStatusCode();
                    List<string> sCat = new List<string>();
                    List<PostCategory> lpc = (await rpCat.Content.ReadAsAsync<IEnumerable<PostCategory>>()).ToList();
                    foreach (PostCategory cat in lpc) {
                        HttpResponseMessage rcd = await client.GetAsync("api/CategoryData/?$filter=categoryid eq " + cat.category);
                        rcd.EnsureSuccessStatusCode();
                        CategoryData cd = (await rcd.Content.ReadAsAsync<IEnumerable<CategoryData>>()).FirstOrDefault();
                        sCat.Add(cd.title);
                    }
                    p.categories = sCat.ToArray();
                    lp.Add(new Post(p));
                }
                bpArr = lp.ToArray();
            }
            catch { }

            return bpArr;
        }

        public async Task<CategoryInfoWP[]> GetCategories(string userName, string password)
        {
            CategoryInfoWP[] catInfo = null;
            HttpClient client = ClientUtility.BlogAPIClient();
            try {
                HttpResponseMessage resp = await client.GetAsync("api/CategoryData/?$filter=username eq '" + userName + "'");
                resp.EnsureSuccessStatusCode();

                IEnumerable<CategoryData> icd = await resp.Content.ReadAsAsync<IEnumerable<CategoryData>>();
                List<CategoryInfoWP> lci = new List<CategoryInfoWP>();
                foreach (CategoryData cd in icd) {
                    lci.Add(new CategoryInfoWP(new CategoryInfo(cd)));
                }
                catInfo = lci.ToArray();
            }
            catch { }

            return catInfo;
        }

        [MaliciousActivityChecksFilter]
        public async Task<int> NewPage(string userName, string password, string blogid, Page page, string license = "")
        {
            PageData pd = new PageData(page, blogid, DateTime.Now);
            HttpClient client = ClientUtility.BlogAPIClient();


            try {
                HttpResponseMessage rLayout = await client.GetAsync("api/BlogData/" + blogid);
                rLayout.EnsureSuccessStatusCode();
                BlogData bd = await rLayout.Content.ReadAsAsync<BlogData>();
                if (!string.IsNullOrEmpty(license)) {
                    pd.license = license;
                } else if (!string.IsNullOrEmpty(bd.license)) {
                    pd.license = bd.license;
                } else if (!string.IsNullOrEmpty((string)HttpContext.Current.Application["__DefaultLicense"])) {
                    pd.license = (string)HttpContext.Current.Application["__DefaultLicense"];
                }

                HttpResponseMessage resp = await client.PostAsXmlAsync("api/PageData", pd);
                resp.EnsureSuccessStatusCode();

                pd = await resp.Content.ReadAsAsync<PageData>();
            }
            catch { }

            return pd.pageid;
        }

        public async Task<Page[]> GetPageList(string userName, string password, string blogid)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage bdResp = await client.GetAsync("api/BlogData/?$filter=username eq '" + userName + "' and blogname eq '" + blogid + "'");
            bdResp.EnsureSuccessStatusCode();
            BlogData bd = (await bdResp.Content.ReadAsAsync<IEnumerable<BlogData>>()).FirstOrDefault();

            HttpResponseMessage bpResp = await client.GetAsync("api/PageData/?$filter=blogid eq '" + bd.blogid + "'");
            bpResp.EnsureSuccessStatusCode();

            List<PageData> pdl = (await bpResp.Content.ReadAsAsync<IEnumerable<PageData>>()).ToList();
            List<Page> pl = new List<Page>();
            foreach (PageData pd in pdl) {
                pl.Add(new Page(pd));
            }
            return pl.ToArray();
        }

        [MaliciousActivityChecksFilter]
        public async Task<int> NewPost(string userName, string password, string blogid, Post post)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            List<CategoryData> cdl = new List<CategoryData>();
            PostData pd = new PostData();
            try {
                foreach (string cat in post.categories) {
                    HttpResponseMessage rcat = await client.GetAsync("api/CategoryData/?$filter=title eq '" + cat + "' and username eq '" + userName + "'");
                    CategoryData cd = new CategoryData();
                    rcat.EnsureSuccessStatusCode();
                    cd = (await rcat.Content.ReadAsAsync<IEnumerable<CategoryData>>()).FirstOrDefault();
                    if (cd == null) {
                        cd = new CategoryData();
                        cd.title = cat;
                        cd.username = userName;
                        HttpResponseMessage cdAdd = await client.PostAsXmlAsync("api/CategoryData", cd);
                        cdAdd.EnsureSuccessStatusCode();

                        cd = await cdAdd.Content.ReadAsAsync<CategoryData>();
                    }
                    cdl.Add(cd);
                }
                pd = new PostData(post, blogid, cdl);
                pd.dateCreated = DateTime.Now;

                HttpResponseMessage rLayout = await client.GetAsync("api/BlogData/" + blogid);
                rLayout.EnsureSuccessStatusCode();
                BlogData bd = await rLayout.Content.ReadAsAsync<BlogData>();
                if (!string.IsNullOrEmpty(bd.license)) {
                    pd.license = bd.license;
                } else if (!string.IsNullOrEmpty((string)HttpContext.Current.Application["__DefaultLicense"])) {
                    pd.license = (string)HttpContext.Current.Application["__DefaultLicense"];
                }

                HttpResponseMessage resp = await client.PostAsXmlAsync("api/PostData", pd);
                resp.EnsureSuccessStatusCode();

                PostData pdResp = await resp.Content.ReadAsAsync<PostData>();
                pd.postid = pdResp.postid;

                foreach (CategoryData cd in cdl) {
                    PostCategory pc = new PostCategory(0, cd.categoryid, pd.postid);
                    HttpResponseMessage rpcat = await client.PostAsXmlAsync("api/PostCategory", pc);
                    rpcat.EnsureSuccessStatusCode();
                }

                if (pd.IsPublished) {
                    HttpResponseMessage rPub = await client.PostAsXmlAsync("api/CurrentPostData", new CurrentPostData(pd));
                    resp.EnsureSuccessStatusCode();
                }
            }
            catch { }
            return pd.postid;
        }

        [MaliciousActivityChecksFilter]
        public async Task EditPost(string userName, string password, Post post)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            List<CategoryData> cdl = new List<CategoryData>();
            PostData pd = new PostData();
            try {
                if (post.categories != null) {
                    foreach (string cat in post.categories) {
                        HttpResponseMessage rcat = await client.GetAsync("api/CategoryData/?$filter=title eq '" + cat + "' and username eq '" + userName + "'");
                        CategoryData cd = new CategoryData();
                        rcat.EnsureSuccessStatusCode();
                        cd = (await rcat.Content.ReadAsAsync<IEnumerable<CategoryData>>()).FirstOrDefault();
                        if (cd == null) {
                            cd = new CategoryData();
                            cd.title = cat;
                            cd.username = userName;
                            HttpResponseMessage cdAdd = await client.PostAsXmlAsync("api/CategoryData", cd);
                            cdAdd.EnsureSuccessStatusCode();

                            cd = await cdAdd.Content.ReadAsAsync<CategoryData>();
                        }
                        cdl.Add(cd);
                    }
                }
                HttpResponseMessage pclResp = await client.GetAsync("api/PostCategory/?$filter=postid eq " + post.postid);
                pclResp.EnsureSuccessStatusCode();
                List<PostCategory> pcl = (await pclResp.Content.ReadAsAsync<IEnumerable<PostCategory>>()).ToList();
                foreach (PostCategory pc in pcl) {
                    HttpResponseMessage pcDel = await client.DeleteAsync("api/PostCategory/" + pc.postcategoryid);
                    pcDel.EnsureSuccessStatusCode();
                }

                HttpResponseMessage rBlog = await client.GetAsync("api/PostData/?$filter=postid eq " + post.postid);
                rBlog.EnsureSuccessStatusCode();
                PostData pdr = (await rBlog.Content.ReadAsAsync<IEnumerable<PostData>>()).FirstOrDefault();
                if (string.IsNullOrEmpty(post.license)) post.license = pdr.license;

                pd = new PostData(post, pdr.blogid, cdl, post.license);
                HttpResponseMessage pdResp = await client.PutAsXmlAsync("api/PostData/" + pd.postid, pd);
                pdResp.EnsureSuccessStatusCode();

                foreach (CategoryData cd in cdl) {
                    PostCategory pc = new PostCategory(0, cd.categoryid, pd.postid);
                    HttpResponseMessage rpcat = await client.PostAsXmlAsync("api/PostCategory", pc);
                    rpcat.EnsureSuccessStatusCode();
                }

                if (pd.IsPublished) {
                    HttpResponseMessage cpdResp = await client.GetAsync("api/CurrentPostData/" + pd.postid);
                    if (cpdResp.IsSuccessStatusCode) {
                        CurrentPostData cpd = await cpdResp.Content.ReadAsAsync<CurrentPostData>();
                        if (cpd != null && cpd.postid == pd.postid) {
                            HttpResponseMessage cpdReplace = await client.PutAsXmlAsync("api/CurrentPostData/" + pd.postid, new CurrentPostData(pd, pd.license));
                            cpdReplace.EnsureSuccessStatusCode();
                        }
                    }
                }
            }
            catch { }
            
        }

        public async Task<Post> GetPost(string userName, string password, int postid)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            PostData pd = new PostData();
            try {
                HttpResponseMessage resp = await client.GetAsync("api/PostData/?$filter=postid eq " + postid);
                resp.EnsureSuccessStatusCode();

                pd = (await resp.Content.ReadAsAsync<IEnumerable<PostData>>()).FirstOrDefault();
                if (pd != null) {
                    HttpResponseMessage rpCat = await client.GetAsync("api/PostCategory/?$filter=postid eq " + pd.postid);
                    rpCat.EnsureSuccessStatusCode();
                    List<string> sCat = new List<string>();
                    List<PostCategory> lpc = (await rpCat.Content.ReadAsAsync<IEnumerable<PostCategory>>()).ToList();
                    foreach (PostCategory cat in lpc) {
                        HttpResponseMessage rcd = await client.GetAsync("api/CategoryData/?$filter=categoryid eq " + cat.category);
                        rcd.EnsureSuccessStatusCode();
                        CategoryData cd = (await rcd.Content.ReadAsAsync<IEnumerable<CategoryData>>()).FirstOrDefault();
                        sCat.Add(cd.title);
                    }
                    pd.categories = sCat.ToArray();
                }
            }
            catch { }
            return new Post(pd);
        }

        [MaliciousActivityChecksFilter]
        public async Task DeletePost(string userName, string password, int postid)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage pclResp = await client.GetAsync("api/PostCategory/?$filter=postid eq " + postid);
            pclResp.EnsureSuccessStatusCode();
            List<PostCategory> pcl = (await pclResp.Content.ReadAsAsync<IEnumerable<PostCategory>>()).ToList();
            foreach (PostCategory pc in pcl) {
                HttpResponseMessage pcDel = await client.DeleteAsync("api/PostCategory/" + pc.postcategoryid);
                pcDel.EnsureSuccessStatusCode();
            }

            HttpResponseMessage pdResp = await client.DeleteAsync("api/PostData/" + postid);
            pdResp.EnsureSuccessStatusCode();

            HttpResponseMessage cpdResp = await client.GetAsync("api/CurrentPostData/" + postid);
            if (cpdResp.IsSuccessStatusCode) {
                CurrentPostData cpd = await cpdResp.Content.ReadAsAsync<CurrentPostData>();
                if (cpd != null && cpd.postid == postid) {
                    HttpResponseMessage cpdReplace = await client.DeleteAsync("api/CurrentPostData/" + postid);
                    cpdReplace.EnsureSuccessStatusCode();
                    
                    //now get the new Current Post and save it
                    pdResp = await client.GetAsync("api/PostData/?$filter=blogid eq '" + cpd.blogid + "' and ispublished eq 1&$order=datecreated desc");
                    pdResp.EnsureSuccessStatusCode();

                    PostData pd = (await pdResp.Content.ReadAsAsync<IEnumerable<PostData>>()).FirstOrDefault();
                    if (pd != null) {
                        cpdReplace = await client.PostAsXmlAsync("api/CurrentPostData", new CurrentPostData(pd, pd.license));
                        cpdReplace.EnsureSuccessStatusCode();
                    }
                }
            }
        }

        public async Task<MediaObjectInfo> NewMediaObject(string userName, string password, MediaObject mediaObject)
        {
            MediaObjectInfo moi = new MediaObjectInfo();

            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage qry = await client.GetAsync("api/MediaObjectData/?$filter=username eq '" + userName + "' and name eq '" + mediaObject.name + "'");
            qry.EnsureSuccessStatusCode();
            MediaObjectData mod = (await qry.Content.ReadAsAsync<IEnumerable<MediaObjectData>>()).FirstOrDefault();
            if (mod == null) {
                HttpResponseMessage resp = await client.PostAsXmlAsync("api/MediaObjectData", new MediaObjectData(0, userName, mediaObject));
                resp.EnsureSuccessStatusCode();

                mod = await resp.Content.ReadAsAsync<MediaObjectData>();
            } else {
                mod.bits = mediaObject.bits;
                mod.type = mediaObject.type;
                HttpResponseMessage upd = await client.PutAsXmlAsync("api/MediaObjectData/" + mod.objectid, mod);
            }

            moi = new MediaObjectInfo(mod.name, "MediaAccess/Media/GetImage/?imgName=" + mod.name, mod.type);

            return moi;
        }

        [MaliciousActivityChecksFilter]
        public async Task EditPage(string userName, string password, int pageid, Page page, string license = "")
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage resp = await client.GetAsync("api/PageData/" + pageid);
            resp.EnsureSuccessStatusCode();
            PageData pd = await resp.Content.ReadAsAsync<PageData>();
            pd.title = page.title;
            pd.description = page.description;
            pd.wp_page_parent_id = page.wp_page_parent_id;
            pd.wp_page_order = page.wp_page_order;
            pd.IsPublished = page.IsPublished;

            if (!string.IsNullOrEmpty(license)) {
                pd.license = license;
            }
            //pd.DateCreated = page.da
            HttpResponseMessage updResp = await client.PutAsXmlAsync("api/PageData/" + pageid, pd);
            updResp.EnsureSuccessStatusCode();
        }

        public async Task<Page> GetPage(string userName, string password, int pageid)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage resp = await client.GetAsync("api/PageData/" + pageid);
            resp.EnsureSuccessStatusCode();

            PageData pd = await resp.Content.ReadAsAsync<PageData>();
            return new Page(pd);
        }

        public async Task<Page[]> GetPages(string userName, string password, string blogid, int noOfPages = 10)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage resp = await client.GetAsync("api/PageData/?$filter=blogid eq '" + blogid + "'&$top=" + noOfPages);
            resp.EnsureSuccessStatusCode();

            List<Page> pages = new List<Page>();
            List<PageData> lpd = (await resp.Content.ReadAsAsync<IEnumerable<PageData>>()).ToList();
            foreach (PageData pd in lpd) {
                pages.Add(new Page(pd));
            }
            return pages.ToArray();
        }

        [MaliciousActivityChecksFilter]
        public async Task DeletePage(string userName, string password, int pageid)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage resp = await client.DeleteAsync("api/PageData/" + pageid);
            resp.EnsureSuccessStatusCode();
        }


        public async Task<PostCategories[]> GetPostCategories(string userName, string password, int postid)
        {
            HttpClient client = ClientUtility.BlogAPIClient();
            HttpResponseMessage rpCat = await client.GetAsync("api/PostCategory/?$filter=postid eq " + postid);
            rpCat.EnsureSuccessStatusCode();
            List<PostCategories> sCat = new List<PostCategories>();
            List<PostCategory> lpc = (await rpCat.Content.ReadAsAsync<IEnumerable<PostCategory>>()).ToList();
            foreach (PostCategory cat in lpc) {
                HttpResponseMessage rcd = await client.GetAsync("api/CategoryData/?$filter=categoryid eq " + cat.category);
                rcd.EnsureSuccessStatusCode();
                CategoryData cd = (await rcd.Content.ReadAsAsync<IEnumerable<CategoryData>>()).FirstOrDefault();
                sCat.Add(new PostCategories(cd));
            }
            return sCat.ToArray();
        }
    }
}
